/******************************************************************************
 * @file     system_adaption.c
 * @brief    系统资源集成文件
 * @author   Ruilist
 * @date     2025-08-27
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *           依赖 system_adaption.h
 *
 * @par 日志:
 * - V1.0.0 2025-08-27 Ruilist
 *****************************************************************************/

//******************************** Includes *********************************//

#include "system_adaption.h"

//******************************** Includes *********************************//

//******************************** Defines **********************************//

bsp_led_handler_t handler_1;
bsp_led_driver_t  led1;
bsp_led_driver_t  led2;

//
led_status_t led_1_on( void )
{
    printf( "led is on\r\n" );
    return LED_OK;
}
led_status_t led_1_off( void )
{
    printf( "led is off\r\n" );
    return LED_OK;
}

led_operations_t led_1_operations = {
    .pf_led_on  = led_1_on,
    .pf_led_off = led_1_off };

led_status_t os_delay_led( const uint32_t delay_time )
{
    osDelay( delay_time );
    return LED_OK;
}

os_delay_t os_delay_led_1 = {
    .pf_os_delay = os_delay_led };

led_status_t time_base_led( uint32_t *const time_stamp )
{
    if ( NULL == time_stamp )
    {
        printf( "StartDefaultTask start \r\n" );
        return LED_ERROR_PARAMETER;
    }
    *time_stamp = 0;
    return LED_OK;
}

time_base_t led_1_time_base = {
    .pf_get_time = time_base_led };

void test1( void )
{
    bsp_led_driver_t led_1;  // led实例1
    bsp_led_driver_t led_2;  // led实例2

    led_status_t ret = LED_OK;

    ret = led_driver_inst( &led_1, &led_1_operations, &led_1_time_base, &os_delay_led_1 );
    if ( LED_OK == ret )
    {
        printf( "led_driver_inst ok \r\n" );
    }
    ret = led_driver_inst( &led_2, &led_1_operations, &led_1_time_base, &os_delay_led_1 );
    if ( LED_OK == ret )
    {
        printf( "led_driver_inst ok \r\n" );
    }
}

led_handler_status_t os_delay_hanler( const uint32_t delay_time )
{
    osDelay( delay_time );
    return HANDLER_OK;
}

handler_os_delay_t handler_1_os_delay = {
    .pf_os_delay = os_delay_hanler };

led_handler_status_t os_queue_create_handler(
    uint32_t const item_num,
    uint32_t const item_size,
    void **const   queue_handler )
{
#ifdef DEBUG
    printf( "os_queue_create_handler \r\n" );
#endif  // DEBUG
    QueueHandle_t temp_queue_handle = NULL;
    temp_queue_handle               = xQueueCreate( item_num, item_size );
    if ( NULL == temp_queue_handle )
    {
        return HANDLER_ERROR_RESOURCES;
    }
    else
    {
        *queue_handler = temp_queue_handle;
        return HANDLER_OK;
    }
}

led_handler_status_t os_queue_put_handler(
    void *const queue_handler,
    void *const item,
    uint32_t    timeout )
{
#ifdef DEBUG
    printf( "os_queue_put_handler \r\n" );
#endif  // DEBUG

    if ( NULL == queue_handler ||
         NULL == item ||
         timeout > portMAX_DELAY )
    {
        return HANDLER_ERROR_RESOURCES;
    }
    else
    {
        if ( pdFALSE == xQueueSend( queue_handler, item, timeout ) )
        {
            return HANDLER_ERROR;
        }
        return HANDLER_OK;
    }
}

led_handler_status_t os_queue_get_handler(
    void *const queue_handler,
    void *const item,
    uint32_t    timeout )
{
#ifdef DEBUG
    printf( "os_queue_get_handler \r\n" );
#endif  // DEBUG

    if ( NULL == queue_handler ||
         NULL == item ||
         timeout > portMAX_DELAY )
    {
        return HANDLER_ERROR_RESOURCES;
    }
    else
    {
        if ( pdPASS == xQueueReceive( queue_handler, item, timeout ) )
        {
            return HANDLER_OK;
        }
        return HANDLER_ERROR;
    }
}

led_handler_status_t os_queue_delete_handler( void *const queue_handler )
{
#ifdef DEBUG
    printf( "os_queue_delete_handler \r\n" );
#endif  // DEBUG
    if ( NULL == queue_handler )
    {
        return HANDLER_ERROR_RESOURCES;
    }
    vQueueDelete( queue_handler );
    return HANDLER_OK;
}

handler_os_queue_t handler1_os_queue = {
    .pf_os_queue_create = os_queue_create_handler,
    .pf_os_queue_put    = os_queue_put_handler,
    .pf_os_queue_get    = os_queue_get_handler,
    .pf_os_queue_delete = os_queue_delete_handler };

led_handler_status_t os_critical_enter_handler( void )
{
#ifdef DEBUG
    printf( "os_critical_enter_handler \r\n" );
#endif  // DEBUG
    vPortEnterCritical();
    return HANDLER_OK;
}

led_handler_status_t os_critical_exit_handler( void )
{
#ifdef DEBUG
    printf( "os_critical_exit_handler \r\n" );
#endif  // DEBUG
    vPortExitCritical();
    return HANDLER_OK;
}

handler_os_critical_t handler1_os_critical = {
    .pf_os_critical_enter = os_critical_enter_handler,
    .pf_os_critical_exit  = os_critical_exit_handler };

led_handler_status_t get_time_handler( uint32_t *const p_os_tick )
{
    if ( NULL == p_os_tick )
    {
        return HANDLER_ERROR_RESOURCES;
    }
    *p_os_tick = HAL_GetTick();
    return HANDLER_OK;
}

handler_time_base_t handler1_time_base = {
    .pf_get_time = get_time_handler };

led_handler_status_t thread_create_handler(                                /* thread_create.         */
                                            void *const       task_code,   /* Defined. Internal*/
                                            const char *const task_name,   /* Defined. external*/
                                            const uint32_t    stack_depth, /* Defined. external*/
                                            void *const       parameters,  /* Defined. Internal*/
                                            uint32_t          priority,    /* Defined. external*/
                                            void **const      task_handler /* Defined. Internal*/
)
{
    BaseType_t ret = pdPASS;
#ifdef DEBUG
    printf( "parameters = [%p]\r\n", parameters );
    printf( "thread_create_handler1 \r\n" );
#endif  // DEBUG
    ret = xTaskCreate( (TaskFunction_t)task_code,
                       "led_handler_1",
                       stack_depth,
                       parameters,
                       (osPriority_t)osPriorityNormal,
                       (TaskHandle_t *)task_handler );

    if ( pdPASS != ret )
    {
#ifdef DEBUG
        printf( "thread_create_handler1 ret = [%d]\r\n", ret );
#endif  // DEBUG
        return HANDLER_ERROR_RESOURCES;
    }
    else
    {
        return HANDLER_OK;
    }
}

led_handler_status_t thread_delete_handler( void *const queue_handler )
{
    led_handler_status_t ret = HANDLER_OK;

    if ( NULL == queue_handler )
    {
        return HANDLER_ERROR_RESOURCES;
    }

    vTaskDelete( queue_handler );

    return ret;
}

handler_os_thread_t handler1_os_thread = {
    .pf_os_thread_create = thread_create_handler,
    .pf_os_thread_delete = thread_delete_handler };

void Test_2( void )
{
    led_handler_status_t ret = HANDLER_OK;

    ret = led_handler_inst( &handler_1,  // 跑在线程3上，Core1
                            &handler_1_os_delay,
                            &handler1_os_queue,
                            &handler1_os_critical,
                            &handler1_os_thread,
                            // tbd &
                            &handler1_time_base );

    printf( "handler_1.pf_led_countroler\r\n" );

    led_status_t ret1 = LED_OK;

    ret1 = led_driver_inst( &led1, &led_1_operations, &led_1_time_base, &os_delay_led_1 );
    if ( LED_OK == ret1 )
    {
        printf( "led1_driver_inst ok \r\n" );
    }

    ret1 = led_driver_inst( &led2, &led_1_operations, &led_1_time_base, &os_delay_led_1 );
    if ( LED_OK == ret1 )
    {
        printf( "led2_driver_inst ok \r\n" );
    }

    led_index_t handler_1_led_index_1 = LED_NOT_INITIALIZED;
    ret                               = handler_1.pf_led_register( &handler_1,  // 跑在线程1上，Core1
                                     &led1,
                                     &handler_1_led_index_1 );

    printf( "The return of handler_1.pf_led_register is [%d]\r\n",
            ret );
    printf( "The registered &led1 index is LED_[%d]\r\n",
            ( handler_1_led_index_1 + 1 ) );

    led_index_t handler_1_led_index_2 = LED_NOT_INITIALIZED;
    ret                               = handler_1.pf_led_register( &handler_1,  // 跑在线程2上，Core2
                                     &led2,
                                     &handler_1_led_index_2 );

    printf( "The return of handler_1.pf_led_register is [%d]\r\n",
            ret );
    printf( "The registered &led2 index is LED_[%d]\r\n",
            ( handler_1_led_index_2 + 1 ) );

    handler_1.pf_led_countroler( &handler_1,
                                 100U,
                                 2U,
                                 DUTY_CYCLE_1_1,
                                 handler_1_led_index_1 );
}

//******************************** Defines **********************************//

//******************************** Declaring ********************************//

//******************************** Declaring ********************************//
